package com.xcf.center.config;

import com.xcf.center.ZookeeperRegisterConfig;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.zookeeper.Watcher;

public class ConfigWatcher {

    private final ZookeeperRegisterConfig zkConfig;
    private final IDataChange dataChange;

    private String nameSpace = "db-config";

    private String dbName = "/db_01";

    private CuratorFramework zookeeperClient;

    private String dbConfig;


    public ConfigWatcher() {
        this(new ZookeeperRegisterConfig(), null);
    }

    public ConfigWatcher(ZookeeperRegisterConfig zkConfig, IDataChange dataChange) {
        this.zkConfig = zkConfig;
        this.dataChange = dataChange;
    }

    public void setNameSpace(String nameSpace) {
        this.nameSpace = nameSpace;
    }

    public String getDbName() {
        return dbName;
    }

    public void init() throws Exception {
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(zkConfig.getConnectSting()) // server地址
                .sessionTimeoutMs(zkConfig.getSessionTimeOut()) // 会话超时时间
                .connectionTimeoutMs(zkConfig.getConnectTimeOut()) // 连接超时时间
                .retryPolicy(zkConfig.getRetryPolicy()) // 重试策略
                .namespace(nameSpace)
                .build(); //

        client.start();
        System.out.println("Zookeeper session established.");
        zookeeperClient = client;
        String dbConfig = initWatcher();
        if (null != dataChange) {
            dataChange.onDataChange(dbConfig);
        }
    }

    private String initWatcher() throws Exception {
        byte[] bytes = zookeeperClient.getData().forPath(dbName);
        dbConfig = new String(bytes);
        zookeeperClient.getData().usingWatcher((CuratorWatcher) event -> {
            if (event.getType() == Watcher.Event.EventType.NodeDataChanged) {
                String dbConfig = initWatcher();
                if (dataChange != null) {
                    dataChange.onDataChange(dbConfig);
                }
            }
        }).forPath(dbName);
        return dbConfig;
    }

    public String getConfig() throws Exception {
        if (dbConfig != null) {
            return dbConfig;
        }
        if (zookeeperClient == null || !zookeeperClient.isStarted()) {
            while (true) {
                if (zookeeperClient != null && zookeeperClient.isStarted()) {
                    break;
                }
            }
        }
        return initWatcher();
    }
}
